﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Backend.JYD.Model.Auth;
using Backend.JYD.Cache;

namespace Backend.JYD.Business
{
    public class MenuManager
    {
        #region const

        private const string key_MenuInfo = "MenuInfo_All";

        private static Dictionary<Int64, List<MenuInfo>> EmpMenuInfoes = new Dictionary<long, List<MenuInfo>>();

        #endregion

        #region DAL

        private static readonly IDAL.Auth.IMenuInfo menuDAL = Factory.DALFactory.CreateEFDAL<IDAL.Auth.IMenuInfo>("DAL.MenuInfoDAL");

        #endregion

        /// <summary>
        /// 增加，删除，修改权限时。
        /// </summary>
        public void ClearEmpMenuInfoes()
        {
            EmpMenuInfoes.Clear();
        }
        /// <summary>
        /// 维护某人的权限时
        /// </summary>
        /// <param name="empId"></param>
        public void ClearMenuInfoesByEmpId(Int64 empId)
        {
            EmpMenuInfoes.Remove(empId);
            this.GetEmpMenuInfoesByEmpId(empId);
        }

        public List<MenuInfo> LoadAllMenuInfo()
        {
            var list = CacheMgr.Instance.GetCachedItem<List<MenuInfo>>(key_MenuInfo);
            if (list == null)
            {
                var temp = menuDAL.GetAllMenuInfo();
                if (temp != null)
                {
                    list = temp.ToList();
                    CacheMgr.Instance.SetCachedItem<List<MenuInfo>>(key_MenuInfo, list);
                }
            }
            return list;
        }


        private List<MenuInfo> LoadEmpMenuInfoes(Int64 empId)
        {
            //1，一级菜单需要权限，无权限，都不显示。有权限，判断子菜单，有可以显示的子菜单才显示。
            //2，子菜单不需要权限的，显示。子菜单需要权限，有权限的才显示。
            var all = this.LoadAllMenuInfo();
            if (all == null) return null;
   
            var list = new List<MenuInfo>();
            var authInfos = new AuthManager().GetEmpAuthorityInfoesByEmpId(empId);

            foreach(var info in all)
            {
                if (info.MenuAuthInfoes == null || info.MenuAuthInfoes.Count <=0)
                {
                    list.Add(info);
                    continue;
                }
                if(authInfos == null) continue;

                if (info.MenuAuthInfoes.ToList().Exists(p => authInfos.Exists(p1 => p1.AuthId == p.AuthId)))
                {
                    list.Add(info);
                }
            }
            var temp = new List<MenuInfo>(list);
            foreach (var info in temp)
            {
                var isLeaf = !all.Exists(p => p.MenuId.StartsWith(info.MenuId) && p.MenuId != info.MenuId);
                if (isLeaf)
                {
                    var hasParent = list.Exists(p => info.MenuId.StartsWith(p.MenuId) && p.MenuId != info.MenuId);
                    if (!hasParent)
                    {
                        //确定策略，当父级目录不显示的时候，子目录不能显示。
                        list.RemoveAll(p=>p.MenuId == info.MenuId);
                    }
                }
                else
                {
                    var hasChild = list.Exists(p => p.MenuId.StartsWith(info.MenuId) && p.MenuId != info.MenuId);
                    if (!hasChild)
                    {
                        //当父级目录，没有可显示的子目录时，父级目录也不显示
                        list.RemoveAll(p => p.MenuId == info.MenuId);
                    }
                }
            }

            return list;
        }
        private List<MenuInfo> GetMenuChildren(MenuInfo parent, List<MenuInfo> allInfo)
        {
            if(allInfo == null) return null;
            return allInfo.FindAll(p => p.Level == parent.Level + 1 && p.MenuId.StartsWith(parent.MenuId));
        }

        public List<MenuInfo> GetEmpMenuInfoesByEmpId(Int64 empId)
        {
            if (EmpMenuInfoes.ContainsKey(empId))
                return EmpMenuInfoes[empId];

            var infos = this.LoadEmpMenuInfoes(empId);
            if (infos != null && infos.Count > 0)
            {
                EmpMenuInfoes.Add(empId, infos);
            }
            return infos;
        }
    }
}
